<?php

declare(strict_types=1);

namespace App\Controller;

use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
use Swoole\Http\Request;
use Swoole\Server;
use Swoole\Websocket\Frame;
use Swoole\WebSocket\Server as WebSocketServer;
use Hyperf\DbConnection\Db;
use App\Model\UserMessage;
use App\Service\WebsocketRedisCurd;
use Hyperf\Utils\ApplicationContext;

class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
{


    public function onMessage($server, Frame $frame): void
    {
        //消息
        $data = json_decode($frame->data, true);

        $uid = $data['id'];
        $type = $data['type'];
        $redis = new WebsocketRedisCurd();

        switch ($type) {
            case 'index':
                $fd = $redis->getFid($uid);
                if ($fd) {
                    if ($server->isEstablished((int)$fd)) {
                        $data = $redis->getUserList($uid);
                        if (!empty($data)) {
                            foreach ($data as $key => $value) {
                                $info[$key]['user'] = $redis->getUserInfo($value);
                                $res = $redis->getLastMessage($value, $uid);
                                $info[$key]['last_messge'] = $res;
                            }
                            $server->push((int)$fd, 'list: ' . json_encode($info));
                        }
                    }
                }
                break;
            case 'message_index':
                $toid = $data['toid'];
                $fd = $redis->getFid($toid);
                if ($fd) {
                    if ($server->isEstablished((int)$fd)) {
                        $res = $redis->getUserMessage($toid, $uid);
                        foreach ($res as $key => $value) {
                            //var_dump($value);
                            $server->push((int)$fd, 'content: ' . json_encode(unserialize($value)));
                        }
                    }
                }
                break;
            case 'message':
                $toid = $data['toid'];
                $content = $data['content'];
                $redis->setUserList($toid, $uid);
                $redis->setLastMessage($uid, $toid, $content);
                $userMessage = UserMessage::create(['uid' => $uid, 'pfid' => 1, 'touid' => $toid, 'content' => $content]);
                $redis->setNewUserMessage($uid, $toid, 1, $content);
                $fd = $redis->getFid($toid);
                if ($fd) {
                    if ($server->isEstablished((int)$fd)) {
                        $value['content'] = $content;
                        $value['mid'] = 1;
                        $value['datetime'] = date('Y-m-d H:i:s');
                        $server->push((int)$fd, 'content: ' . json_encode($value));
                    }
                }
                break;
            default:
                # code...
                break;
        }
    }

    public function onClose($server, int $fd, int $reactorId): void
    {
        // Db::update('UPDATE user set fid = ? WHERE fid = ?', [0, $fd]); // 返回受影响的行数 int
    }

    public function onOpen($server, Request $request): void
    {
        $server->push($request->fd, '链接成功');
        $id = $request->get['id'];
        $redis = new WebsocketRedisCurd();

        $redis->setFid($id, $request->fd);
        if ($server->isEstablished($request->fd)) {
            $data = $redis->getUserList($id);
            if (!empty($data)) {
                foreach ($data as $key => $value) {
                    $info[$key]['user'] = $redis->getUserInfo($value);
                    $res = $redis->getLastMessage($value, $id);
                    $info[$key]['last_messge'] = $res;
                }
                $info['type'] = 'index';
                $server->push($request->fd, 'list: ' . json_encode($info));
            }
        }
    }
}
